/*
 *  Лицензия MIT
 * 
 *  Copyright 2011 Salnikov Aleksey.
 * 
 *  Данная лицензия разрешает, безвозмездно, лицам, получившим копию данного программного обеспечения
 *  и сопутствующей документации (в дальнейшем именуемыми "Программное Обеспечение"),
 *  использовать Программное Обеспечение без ограничений, включая неограниченное право
 *  на использование, копирование, изменение, объединение, публикацию, распространение,
 *  сублицензирование и/или продажу копий Программного Обеспечения, также как и лицам,
 *  которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:
 * 
 *  Вышеупомянутый копирайт и данные условия должны быть включены во все копии или значимые
 *  части данного Программного Обеспечения.
 * 
 *  ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ ЛЮБОГО ВИДА ГАРАНТИЙ,
 *  ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ ГАРАНТИЯМИ ТОВАРНОЙ ПРИГОДНОСТИ,
 *  СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И НЕНАРУШЕНИЯ ПРАВ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ
 *  НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО ИСКАМ О ВОЗМЕЩЕНИИ УЩЕРБА, УБЫТКОВ ИЛИ ДРУГИХ ТРЕБОВАНИЙ
 *  ПО ДЕЙСТВУЮЩИМ КОНТРАКТАМ, ДЕЛИКТАМ ИЛИ ИНОМУ, ВОЗНИКШИМ ИЗ, ИМЕЮЩИМ ПРИЧИНОЙ ИЛИ СВЯЗАННЫМ
 *  С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ ИЛИ ИСПОЛЬЗОВАНИЕМ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
 *  ИЛИ ИНЫМИ ДЕЙСТВИЯМИ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
 */

package look;

import CommonTools.Admin;
import CommonTools.DesignTools;
import CommonTools.Settings;
import Interfaces.AdminInterface;
import java.awt.AWTException;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.MenuItem;
import java.awt.PopupMenu;
import java.awt.SystemTray;
import java.awt.TrayIcon;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPasswordField;
import javax.swing.JSeparator;
import javax.swing.JTextField;

/**
 * Окно аутентификации пользователя (администратора) в программе
 *
 * @author Salnikov Aleksey
 */
public class LoginWindow extends JFrame
{

    protected JLabel loginL, passwordL;
    protected JTextField loginF;
    protected JPasswordField passwordF;
    protected final JButton enterB;
    protected char pass = '•';
    protected char unPass = '\0';
    protected JCheckBox showPassword;
    private Admin admin = null;
    protected SystemTray systemTray;
    protected TrayIcon trayIcon;
    protected DemandsWindow dwindow = null;

    protected final static String ADMIN_SERVER_NAME = "AdminServer";

    public LoginWindow()
    {
        super("Вход | Admin Ordo");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        /*****************************************************
         * Создание компонентов и их размещение на форме
         ****************************************************/

        Container c = this.getContentPane();
        c.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.weightx = 0.5;
        gbc.weighty = 0.5;
        gbc.anchor = gbc.NORTHWEST;

        //Создаем метку для логина
        loginL = new JLabel("Логин:");
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.insets = new Insets(25,20,0,5);
        gbc.fill = gbc.NONE;
        c.add(loginL, gbc);

        //Создаем поле для логина
        loginF = new JTextField();
        gbc.gridx = 1;
        gbc.insets = new Insets(20,0,0,20);
        gbc.ipadx = 200;
        gbc.fill = gbc.HORIZONTAL;
        c.add(loginF, gbc);

        loginF.addKeyListener(new KeyAdapter()
            {
                public void keyTyped(KeyEvent e)
                {
                    enterEnabled();
                }
            });

        //Создаем метку пароля
        passwordL = new JLabel("Пароль:");
        gbc.gridx = 0;
        gbc.gridy = 1;
        gbc.insets = new Insets(5,20,0,5);
        gbc.ipadx = 0;
        c.add(passwordL, gbc);

        //Создаем поле пароля
        passwordF = new JPasswordField();
        passwordF.setEchoChar(pass);
        gbc.gridx = 1;
        gbc.insets = new Insets(0,0,0,20);
        c.add(passwordF, gbc);

        passwordF.addKeyListener(new KeyAdapter()
            {
            @Override
                public void keyTyped(KeyEvent e)
                {
                    enterEnabled();
                }
            });

        //Создаем флажок отображения пароля
        showPassword = new JCheckBox("Отобразить пароль");
        gbc.gridy = 2;
        c.add(showPassword, gbc);

        showPassword.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    hidePassword();
                }
            });

        //Создаем кнопку
        enterB = new JButton("Войти");
        enterB.setEnabled(false);
        gbc.gridy = 3;
        gbc.insets = new Insets(0,0,20,20);
        c.add(enterB, gbc);

        enterB.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    enter();
                }
            });

        icon();
        popupMenu();

        /*****************************************************
         * Последняя подготовка к показу
         ****************************************************/
        this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        DesignTools.centeredWindow(this);
        this.setResizable(false);
        this.pack();
        this.validate();
        this.setVisible(true);
    }

    //Делаем кнопку доступной
    protected void enterEnabled()
    {
        enterB.setEnabled((loginF.getText().length() > 0) && (passwordF.getText().length() > 0));
    }

    //Делаем видимым пароль
    protected void hidePassword()
    {
        if (showPassword.isSelected())
            passwordF.setEchoChar(this.unPass);
        else
            passwordF.setEchoChar(this.pass);
    }

    //производим вход и проверку
    protected void enter()
    {
        //Подключаемся к серверу
        String login = loginF.getText();
        String password = passwordF.getText();
        String ip = Settings.getParametrValue("serverip");
        String port = Settings.getParametrValue("serverport");

        //Регистрируемся в rmi
        String rmi = "rmi://" + ip + ":" + port + "/" + ADMIN_SERVER_NAME;
        try {
            AdminInterface ai = (AdminInterface) Naming.lookup(rmi);
            admin = ai.authenticate(login, password);
            if (admin != null)
            {
                this.dispose();
                popupMenu();
                this.showDemandsWindow();
            }
            else
                DesignTools.showMessage("Ошибка", "Логин и/или пароль указаны неверно", false);
        } catch (NotBoundException ex) {
            DesignTools.showMessage("Авторизация не произведена", "Возможно, отключен сервер, или неверные настройки\n"
                        + "ip адреса сервера и порта. Пожалуйста, проверьте их.", false);
        } catch (MalformedURLException ex) {
            DesignTools.showMessage("Авторизация не произведена", "Возможно, отключен сервер, или неверные настройки\n"
                        + "ip адреса сервера и порта. Пожалуйста, проверьте их.", false);
        } catch (RemoteException ex) {
            DesignTools.showMessage("Авторизация не произведена", "Возможно, отключен сервер, или неверные настройки\n"
                        + "ip адреса сервера и порта. Пожалуйста, проверьте их.", false);
        }
    }

    /**
     * Метод добавления иконки в трей
     */
    protected void icon()
    {
        ImageIcon icon = new ImageIcon("images/icon.png");

        //Устанавливаем для иконки окна и системного трея
        this.setIconImage(icon.getImage());
        systemTray = SystemTray.getSystemTray();
        trayIcon = new TrayIcon(icon.getImage());
        try {
            systemTray.add(trayIcon);
        } catch (AWTException ex) {
            DesignTools.showMessage("Информация", "Не удается поместить программу в трей", true);
        }
        this.setLocationRelativeTo(null);
    }

    /**
     * Создание поп-ап меню для иконки
     */
    protected void popupMenu()
    {
        //Создаем поп-ап меню
        PopupMenu popup = new PopupMenu();

        //Просмотр заявок
        MenuItem showDemands = new MenuItem("Список заявок");
        MenuItem exit = new MenuItem("Закрыть");

        MenuItem admins = new MenuItem("Администраторы");
        MenuItem settings = new MenuItem("Настройки");

        if (admin != null)
        {
            popup.add(showDemands);
            //if (admin.getLogin().equals("root"))
            if (admin.isRoot())
            {
                popup.add(admins);
                
                admins.addActionListener(new ActionListener()
                {
                    public void actionPerformed(ActionEvent e)
                    {
                        try {
                            showAdminWindow();
                        } catch (RemoteException ex) {
                            Logger.getLogger(LoginWindow.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                });
            }
        }
        popup.add(settings);
        popup.add(exit);
        trayIcon.setPopupMenu(popup);


        /*****************************************************
         * Привязывае события к кнопкам
         ****************************************************/
         showDemands.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                try {
                    showDemandsWindow();
                } catch (RemoteException ex) {
                    Logger.getLogger(LoginWindow.class.getName()).log(Level.SEVERE, null, ex);
                }
                }
            });

        exit.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    exit();
                }
            });

        settings.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    showSettings();
                }
            });

        trayIcon.addActionListener(new ActionListener()
            {
                public void actionPerformed(ActionEvent e)
                {
                    showMe();
                }
            });
    }

    /**
     * Функция показа окна с заявками
     */
    protected void showDemandsWindow() throws RemoteException
    {
        if (dwindow == null)
        {
            dwindow = new DemandsWindow(admin);
        }
        if (dwindow != null)
        {
            dwindow.setVisible(true);
        }
    }

    /**
     * Функция отображения окна управления администраторами
     */
    protected void showAdminWindow() throws RemoteException
    {
        AdminManagerWindow amw = new AdminManagerWindow();
    }

    /**
     * Функция выхода из приложения
     */
    protected void exit()
    {
        System.exit(0);
    }

    /**
     * Функция показа своего окна
     */
    protected void showMe()
    {
        this.setVisible(!this.isVisible());
    }

    protected void showSettings()
    {
        SettingsWindow sw = new SettingsWindow();
    }
}
